﻿using System;
using log4net;
using log4net.Appender;
using log4net.Layout;
using log4net.Repository.Hierarchy;

namespace cludg.Infrastructure.Core.Logging
{
	public class Log4NetLogger : ILogger
	{

		private string _loggerName;
	
		private readonly ILog _logger; 

		public Log4NetLogger(string loggerName)
		{
			_loggerName = loggerName;
			_logger = LogManager.GetLogger(_loggerName);
			log4net.Config.XmlConfigurator.Configure();
		}

		/// <summary>
		/// Debug messages
		/// </summary>
		/// <param name="message"></param>
		public void Debug(object message)
		{
			_logger.Debug(message);
		}
		/// <summary>
		/// Debug messages with trace
		/// </summary>
		/// <example>
		/// ...catch(Exception _ex)
		/// {
		///		LogManager.Instance.Debug("My message", _ex);
		/// }
		/// </example>
		/// <param name="message"></param>
		/// <param name="exception"></param>
		public void Debug(object message, Exception exception)
		{
			_logger.Debug(message,exception);
		}
		/// <summary>
		/// Formated debug messages
		/// </summary>
		/// <param name="format"></param>
		/// <param name="args"></param>
		public void DebugFormat(string format, params object[] args)
		{
			_logger.DebugFormat(format, args);
		}
		/// <summary>
		/// Info messages
		/// </summary>
		/// <param name="message"></param>
		public void Info(object message)
		{
			_logger.Info(message);
		}
		/// <summary>
		/// Info messages with trace
		/// </summary>
		/// <example>
		/// ...catch(Exception _ex)
		/// {
		///		LogManager.Instance.Info("My message", _ex);
		/// }
		/// </example>
		/// <param name="message"></param>
		/// <param name="exception"></param>
		public void Info(object message, Exception exception)
		{
			_logger.Info(message,exception);
		}
		/// <summary>
		/// Formated info message
		/// </summary>
		/// <param name="format"></param>
		/// <param name="args"></param>
		public void InfoFormat(string format, params object[] args)
		{
			_logger.InfoFormat(format, args);
		}
		/// <summary>
		/// Warning message
		/// </summary>
		/// <param name="message"></param>
		public void Warn(object message)
		{
			_logger.Warn(message);
		}
		/// <summary>
		/// Warning message with trace
		/// </summary>
		/// <example>
		/// ...catch(Exception _ex)
		/// {
		///		LogManager.Instance.Warn("My message", _ex);
		/// }
		/// </example>
		/// <param name="message"></param>
		/// <param name="exception"></param>
		public void Warn(object message, Exception exception)
		{
			_logger.Warn(message,exception);
		}
		/// <summary>
		/// Formated warning message
		/// </summary>
		/// <param name="format"></param>
		/// <param name="args"></param>
		public void WarnFormat(string format, params object[] args)
		{
			_logger.WarnFormat(format, args);
		}
		/// <summary>
		/// Error message
		/// </summary>
		/// <param name="message"></param>
		public void Error(object message)
		{
			_logger.Error(message);
		}
		/// <summary>
		/// Error message with trace exception
		/// </summary>
		/// <example>
		/// ...catch(Exception _ex)
		/// {
		///		LogManager.Instance.Error("My message", _ex);
		/// }
		/// </example>
		/// <param name="message"></param>
		/// <param name="exception"></param>
		public void Error(object message, Exception exception)
		{
			_logger.Warn(message, exception);
		}
		/// <summary>
		/// Formated error messages
		/// </summary>
		/// <param name="format"></param>
		/// <param name="args"></param>
		public void ErrorFormat(string format, params object[] args)
		{
			_logger.WarnFormat(format, args);
		}
		/// <summary>
		/// Fatal messages
		/// </summary>
		/// <param name="message"></param>
		public void Fatal(object message)
		{
			_logger.Fatal(message);
		}
		/// <summary>
		/// Fatal messages with exception traced
		/// </summary>
		/// <example>
		/// ...catch(Exception _ex)
		/// {
		///		LogManager.Instance.Fatal("My message", _ex);
		/// }
		/// </example>
		/// <param name="message"></param>
		/// <param name="exception"></param>
		public void Fatal(object message, Exception exception)
		{
			_logger.Fatal(message,exception);
		}
		/// <summary>
		/// Formated fatal messages
		/// </summary>
		/// <param name="format"></param>
		/// <param name="args"></param>
		public void FatalFormat(string format, params object[] args)
		{
			_logger.FatalFormat(format,args);
		}

		// Set the level for a named logger
		public static void SetLevel(string loggerName, string levelName)
		{
			ILog log = log4net.LogManager.GetLogger(loggerName);
			Logger l = (Logger)log.Logger;

			l.Level = l.Hierarchy.LevelMap[levelName];
		}

		// Add an appender to a logger
		public static void AddAppender(string loggerName, IAppender appender)
		{
			ILog log = log4net.LogManager.GetLogger(loggerName);
			Logger l = (Logger)log.Logger;

			l.AddAppender(appender);
		}

		// Create a new file appender
		public static IAppender CreateFileAppender(string name, string fileName)
		{
			FileAppender appender = new
				FileAppender();
			appender.Name = name;
			appender.File = fileName;
			appender.AppendToFile = true;

			PatternLayout layout = new PatternLayout();
			layout.ConversionPattern = "%date [%thread] %-5level - %message%newline";
			layout.ActivateOptions();

			appender.Layout = layout;
			appender.ActivateOptions();

			return appender;
		}
	}
}
